package flexulous.util;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import org.w3c.dom.NodeList;
import flex2.tools.oem.Application;
import flex2.tools.oem.Configuration;
import java.io.*;
import org.gjt.sp.util.Log;
import java.util.*;
import org.gjt.sp.jedit.GUIUtilities;

import flexulous.Flexulous;
import flexulous.FlexulousPlugin;
import flexulous.model.FlexulousTarget;

public class FlexulousCompilerHelper extends Observable implements Observer
{
	
	public static final int COMPILED = 1;
	public static final int OUTPUT_FILE_NOT_FOUND = 2;
	public static final int SOURCE_FILE_NOT_FOUND = 3;
	public static final int COMPILE_PROGRESS_START = 4;
	public static final int COMPILE_PROGRESS_END = 5;
	public static final int COMPILE_PROGRESS = 6;
    public static final int BUILD_FAILED = 7;
	
	private FlexulousTarget target;
	public FlexulousTarget getTarget()
	{
		return target;
	}
	
	public void setTarget(FlexulousTarget target)
	{
		this.target = target;
	}
	
	private FlexulousCompileThread thread;	
	/**
	 * Returns the value of thread.
	 */
	public FlexulousCompileThread getThread()
	{
		return thread;
	}

	/**
	 * Sets the value of thread.
	 * @param thread The value to assign thread.
	 */
	public void setThread(FlexulousCompileThread thread)
	{
		this.thread = thread;
	}
	
	
	private boolean compiled = false;
	public boolean hasCompiled()
	{
		return compiled;
	}
	
	public FlexulousCompilerHelper(FlexulousTarget target)
	{
		this.target = target;
	}
	
	private Application application;
	private Configuration config;
	
	public void compileTarget()
	{
		try {
			// Make sure the file exists.
			File sourceFile = new File(target.getSource());
			//Does the source file exist?
			if(sourceFile.exists()){
				if(application == null){
					application = new Application(sourceFile);
					application.setOutput(new File(target.getOutput()));
					application = new Application(new File(target.getSource()));
					
					application.setOutput(new File(target.getOutput()));
					config = application.getDefaultConfiguration();
					// Enable ActionScript optimizer. config.optimize(true);
					ArrayList<String> configFiles = target.getConfigFiles();
					for(int i=0;i<configFiles.size();i++){
						File configFile = new File(configFiles.get(i));
						if(configFile.exists()){
							config.addConfiguration(configFile);
						}else{
							String[] args = { configFiles.get(i) };
							GUIUtilities.error(null, "config-file-not-found", args);
						}
						
					}
					if(target.getDebug()){
						config.enableDebugging(target.getDebug(), "");
					}
					
					// Apply the new configuration to the Application.
					application.setConfiguration(config);
				}
				
				//Clear the error source.
				FlexulousPlugin.getErrorSource().clear();
				System.gc();
				thread = new FlexulousCompileThread(application, target);
				thread.addObserver(this);
				Thread t = new Thread(thread);
				t.start();
			}else{
				//The source file does not exist!
				String[] args = { target.getSource() };
				GUIUtilities.error(null, "source-file-not-found", args);
			}
			
		} catch (Exception ex) {
			Log.log(Log.WARNING, Flexulous.class, "WTF:");
			Log.log(Log.ERROR, Flexulous.class, ex);
		}
		
	}
	
	public void clearTarget()
	{
		application = null;
		config = null;
	}
	
	public void update(Observable o, Object arg)
	{
		int updateFlag =(Integer)arg;
		switch(updateFlag){
			case COMPILED:
				//GUIUtilities.message(null, "application-compiled", null);
			break;                              
			case OUTPUT_FILE_NOT_FOUND:
				String[] args = { target.getOutput() };
				GUIUtilities.error(null, "output-file-not-found", args);
			break;
			
		}
		setChanged();
		notifyObservers(arg); //pass them on to who's interested.
	}
	
}
